#-------------------------------------------------------------------------------
# Name:        Connect 4
# Purpose:
#
# Connect 4
# 7 columns, 6 rows
# X player 1, O player 2
#
#Diagonal not yet working
#-------------------------------------------------------------------------------
#!/usr/bin/env python

empty = '.' #keyword for empty symbol

class Board(object):
    """board of pieces"""
    def __init__(self):
        self.board = [[empty]*7 for i in range(6)] #6x7 grid board[row][slot]

    def printBoard(self):
        """Display the board array"""
        #print self.board
        alph = (['a','b','c','d','e','f'])
        alph.reverse()
        for i in range(6):
            print alph[i],
            for j in range(7):
                print self.board[i][j],
            print "\n",
        print ' ',
        for j in range(7):
            print j,
        print "\n"

    def playMove(self,symbol,slot):
        """Put piece in for player 1 or 2 in chosen slot 1-7 player 1: 'X', player 2: 'O' | Returns 'legal' or 'illegal' for move types"""
        #check whether it is the current player's turn and whether the move is legal
        slot = int(slot)
        #check if slot was correct number 0-6
        if slot < 0 or slot > 6:
            return 'illegal'

        #check if slot is already filled
        if self.board[0][slot] != empty:
            return 'illegal'

        #Check legaility for Player 1, 'X'
        countX = self.countPieces('X')
        countO = self.countPieces('O')

        if symbol == 'X':
            if countX != countO:
                return 'illegal'
        if symbol == 'O':
            if countO != (countX - 1): #Plyaer 1, 'X', should be one move ahead on O's turn
                return 'illegal'

        row = 0

        #if bottom is open, then put in symbol
        if self.board[5][slot] == empty:
            self.board[5][slot] = symbol
            return 'legal'

        while 1:
            #if there is a symbol, drop to next highest
            #advance the row being looked at
            if (self.board[row][slot] == 'X' or self.board[row][slot] == 'O') and (row != 0):
                self.board[row-1][slot] = symbol #symbol drops on top of pieces in column slot
                return 'legal'
            if self.board[row][slot] == empty:
                row += 1

    def countPieces(self,symbol):
        symbolCount = 0
        for i in range(6):
            for j in range(7):
                if self.board[i][j] == symbol:
                    symbolCount += 1
        return symbolCount

    def winCheck(self):
        """Return player who won, 'X' or 'O' or 'D' for draw or 'N' for none"""
        def tieChecker(self):
            #check if board is filled
            fillflag = 0
            for i in range(7):
                if self.board[0][i] == empty:
                    fillflag = 1
            if fillflag == 0:
                return 'D'
            else:
                return 'A'

        def winH(self):
            def neighborcheck(self,symbol,i,j):
                #return True if won, False if not
                if self.board[i][j] == symbol and self.board[i][j-1] == symbol and self.board[i][j-2] == symbol and self.board[i][j-3] == symbol:
                    return symbol
                else:
                    return 'A'

            """Win horizontally?"""
            for i in range(6):
                for j in range(3,7): #check to left of rows from 3 to 7
                    if self.board[i][j] == empty:
                        continue
                    currentsym = self.board[i][j]
                    if neighborcheck(self,currentsym,i,j) == currentsym: #Checks to see if there's 4 in a row
                        return currentsym
            return 'A'

        def winV(self):
            """Win vertically?"""
            def neighborcheck(self,symbol,i,j):
                #return True if won, False if not
                if self.board[i][j] == symbol and self.board[i-1][j] == symbol and self.board[i-2][j] == symbol and self.board[i-3][j] == symbol:
                    return symbol
                else:
                    return 'A'

            for i in range(3,6):
                for j in range(7): #check to top of slots from 3 to 6
                    if self.board[i][j] == empty:
                        continue
                    currentsym = self.board[i][j]
                    if neighborcheck(self,currentsym,i,j) == currentsym: #Checks to see if there's 4 in a row
                        return currentsym
            return 'A'

        def winDiag(self):
            def toUpLeft(self):
                def neighborcheck(self,symbol,i,j):
                    #return symbol of winner if won, False/junk if not
                    if self.board[i][j] == symbol and self.board[i-1][j-1] == symbol and self.board[i-2][j-2] == symbol and self.board[i-3][j-3] == symbol:
                        return symbol
                    else:
                        return 'A'

                for i in range(3,6):
                    for j in range(3,7): #check to top of slots from 3 to 6
                        if self.board[i][j] == empty:
                            continue
                        currentsym = self.board[i][j]
                        if neighborcheck(self,currentsym,i,j) == currentsym: #Checks to see if there's 4 in a row
                            return currentsym
                return 'A'

            def toUpRight(self): #Not yet completed
                def neighborcheck(self,symbol,i,j):
                    #return True if won, False if not
                    if self.board[i][j] == symbol and self.board[i+1][j-1] == symbol and self.board[i+2][j-2] == symbol and self.board[i+3][j-3] == symbol:
                        return symbol
                    else:
                        return 'A'

                for i in range(0,3):
                    for j in range(3,7): #check to top of slots from 3 to 6
                        if self.board[i][j] == empty:
                            continue
                        currentsym = self.board[i][j]
                        if neighborcheck(self,currentsym,i,j) == currentsym: #Checks to see if there's 4 in a row
                            return currentsym
                return 'A'

            #*****
            #Start of winDiag
            if toUpLeft(self) == 'X' or toUpRight(self) == 'X':
                return 'X'
            if toUpLeft(self) == 'O' or toUpRight(self) == 'O':
                return 'O'


        #Start of winCheck() code
        if tieChecker(self) == 'D':
            return 'D'
        if winH(self) == 'X' or winV(self) == 'X' or winDiag(self) == 'X':
            return 'X'
        if winH(self) == 'O' or winV(self) == 'O' or winDiag(self) == 'O':
            return 'O'
        return 'N' #no win or draw
